/*
Automatic clinic tests using a robot arm.
Copyright (C) 2010  CIC-CPC, CHU Gabriel Montpied
All other trademarks, logos and copyrights are the property
of their respective owners.

This file is part of cpc-painbot.

cpc-painbot is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpc-painbot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with cpc-painbot.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "include/assistantupanddown.h"
#include "ui_assistantupanddown.h"

#include <QProgressDialog>
#include <QFile>

#include "seuil/determination.h"
#include "seuil/methode/upanddown.h"

#include "upanddowndialog.h"

AssistantUpAndDown::AssistantUpAndDown(QWidget *parent) :
    QWizard(parent),
    ui(new Ui::AssistantUpAndDown)
{
    setDefaultProperty("QDoubleSpinBox", "value", SIGNAL(valueChanged(double)));
    ui->setupUi(this);
}

AssistantUpAndDown::~AssistantUpAndDown()
{
    delete ui;
}

void AssistantUpAndDown::accept()
{
    //! \todo Améliorer la gestion de la mémoire.
    //! \todo Généraliser en un seul assistant ?
    // Récupération des paramètres.
    seuil::Determination::Type  type_determination =
                                        seuil::Determination::Type(field("determination").toInt());

    seuil::Methode::Type        type_methode = seuil::Methode::Type(field("methode").toInt());
    Stimulateur::Type           type_stimulateur = Stimulateur::Type(field("stimulateur").toInt());

    // Création de la détermination.
    seuil::Determination *determination =
            seuil::Determination::creer(type_determination, type_methode, type_stimulateur, this);

    // Méthode Up And Down.
    seuil::methode::UpAndDown *methode =
            qobject_cast<seuil::methode::UpAndDown*>(determination->methode());

    // Chargement du rack.
    QFile rackFile(field("stimulateur.rack").toString());
    rackFile.open(QIODevice::ReadOnly | QIODevice::Text);
    methode->setRack(Rack::charger(&rackFile, methode));

    // Création du Dialog associé à l'UpAndDown.
    UpAndDownDialog *dialog = new UpAndDownDialog(this);

    // Lien des signaux issus de la méthode.
    connect(methode, SIGNAL(phaseChangee(int)), dialog, SLOT(changementPhase(int)));
    connect(methode, SIGNAL(erreur(QString)), dialog, SLOT(erreur(QString)));
    connect(methode, SIGNAL(termineeChange(bool)), dialog, SLOT(terminer(bool)));

    // Signal issu de la boîte de dialogue pour indiquer la douleur.
    connect(dialog, SIGNAL(douleurRecue(QVariant)), methode, SLOT(douleur(QVariant)));

    // Lien des signaux issus du Stimulateur.
    Stimulateur *stimulateur = determination->stimulateur();
    connect(stimulateur, SIGNAL(started()), dialog->attente(), SLOT(show()));
    connect(stimulateur, SIGNAL(finished()), dialog->attente(), SLOT(accept()));
    connect(dialog->attente(), SIGNAL(canceled()), stimulateur, SLOT(stop()));
    // Action de stimulation.
    connect(dialog, SIGNAL(stimuler()), stimulateur, SLOT(stimuler()));


    // Configuration de la zone.
    stimulateur->zone()->setRayonMax(field("zone.rayonMax").toDouble());
    stimulateur->zone()->setRayonMin(field("zone.rayonMin").toDouble());

    // Afficher le dialogue une fois cet assistant terminé.
    connect(this, SIGNAL(accepted()), dialog, SLOT(show()));

    // Préparation de la détermination.
    determination->preparer();

    QWizard::accept();
}

void AssistantUpAndDown::changeEvent(QEvent *e)
{
    QWizard::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
